package com.moly.websocketone.configuration.websocket;

import com.moly.websocketone.configuration.websocket.Interceptor.WebsocketHandShakeIntecepter;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.simp.config.ChannelRegistration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.messaging.simp.stomp.StompCommand;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.messaging.support.ChannelInterceptor;
import org.springframework.messaging.support.MessageHeaderAccessor;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

import javax.security.auth.Subject;
import java.security.Principal;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description:  配置 STOMP版  websocket
 * @Author: m01
 * @Date: created at  2018/11/10  17:18
 * @Modified By:
 */
@Configuration
@EnableWebSocketMessageBroker  //在 WebSocket 上启用 STOMP
public class WebsocketConfigWithSpringOverStomp implements WebSocketMessageBrokerConfigurer {


    /**
     * 注册端点，发布或者订阅消息的时候需要连接此端点
     * setAllowedOrigins 非必须，*表示允许其他域进行连接
     * withSockJS  表示开始sockejs支持
     */
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/endpoint-websocket")
                .addInterceptors(new WebsocketHandShakeIntecepter())
                .setAllowedOrigins("*").withSockJS();
    }


    /**
     * 配置消息代理(中介)
     * enableSimpleBroker 服务端推送给客户端的路径前缀
     * setApplicationDestinationPrefixes  客户端发送数据给服务器端的一个前缀
     */
    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/topic", "/chat");
        registry.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.interceptors(new ChannelInterceptor() {

            @Override
            public Message<?> preSend(Message<?> message, MessageChannel channel) {
                StompHeaderAccessor accessor=MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
                if(StompCommand.CONNECT.equals(accessor.getCommand())){
                    String username = accessor.getNativeHeader("username").get(0);
                    String password = accessor.getNativeHeader("password").get(0);
                    for (Map.Entry<String, String> entry : users().entrySet()) {
//                        System.out.println(entry.getKey() + "---" + entry.getValue());
                        if (entry.getKey().equals(username) && entry.getValue().equals(password)) {
                            //验证成功,登录
                            Principal user = new User(username);
                             // access authentication header(s)}
                            accessor.setUser(user);
                            return message;
                        }
                    }
                    return null;

                }
                return message;

            }
        });
    }

    public Map<String,String> users(){

        Map<String, String> user = new HashMap<>();
        user.put("moly", "123456");
        user.put("zqp", "123456");
        return user;
    }
}
class User implements Principal{
    private String name;

    public User(String name){
        this.name = name;
    }
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public boolean implies(Subject subject) {
        return false;
    }
}


/*
* 用户必须登录才能 通信
* 不登录 提示
* */